﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WEB = System.Web;
using System.IO;
using System.Web.SessionState;
using System.Collections.Specialized;

namespace Cymbi.Web
{
    public class HttpContext
        : WEB.HttpContextBase
        , IDisposable
    {
        #region MachManagement
        public class MachManagement
        {
            HttpContext oContext = null;

            internal MachManagement(HttpContext pContext)
            {
                if (pContext == null)
                {
                    throw new InvalidOperationException("Platform is not supported HttpContext is not the MachContext");
                }

                oContext = pContext;
            }

            public void SetCollection(MachCollectionType pType, NameValueCollection pCollection)
            {
                switch (pType)
                {
                    case MachCollectionType.QueryString:
                        ((HttpMachRequest)oContext.oRequest).SetQueryStringCollection(pCollection);
                        break;
                    case MachCollectionType.Form:
                        ((HttpMachRequest)oContext.oRequest).SetFormCollection(pCollection);
                        break;
                }
            }
        }
        #endregion

        #region field variables
        protected static WEB.HttpContextWrapper WrappedContext = null;
        protected static HttpContext MachContext = null;

        private static readonly object @lock = new object();

        protected WEB.HttpRequestBase oRequest = null;
        #endregion

        #region constructor
        public HttpContext()
            : base()
        {
            if (Context != null)
            {
                WrappedContext = new WEB.HttpContextWrapper(Context);
            }
            else
            {
                oRequest = new HttpMachRequest();

                MachContext = this;
            }
        }
        #endregion

        #region private properties
        internal WEB.HttpContext Context { get { return WEB.HttpContext.Current; } }
        #endregion

        #region properties
        public override WEB.HttpApplication ApplicationInstance
        {
            get
            {
                return Context != null ? Context.ApplicationInstance : null;
            }
        }

        public static WEB.HttpContextBase Current
        {
            get
            {
                if (WEB.HttpContext.Current != null)
                {
                    //if (WrappedContext == null)
                    //{
                    //    lock (@lock)
                    //    {
                    //        if (WrappedContext == null)
                    //        {
                    WrappedContext = new WEB.HttpContextWrapper(WEB.HttpContext.Current);
                    //        }
                    //    }
                    //}

                    return WrappedContext;
                }
                else
                {
                    return MachContext;
                }
            }
        }

        //public static void SetServerInstance(WEB.HttpApplication theAppInstance, bool reset)
        //{
        //    if (reset)
        //    {
        //        WrappedContext = null;
        //        MachContext = null;
        //    }

        //    if (theAppInstance != null)
        //    {
        //        Current.ApplicationInstance = theAppInstance;
        //    }
        //    else if (WEB.HttpContext.Current != null)
        //    {
        //        Current.ApplicationInstance = WEB.HttpContext.Current.ApplicationInstance;
        //    }
        //}

        public MachManagement Mach { get { return new MachManagement(MachContext); } }

        public override WEB.HttpRequestBase Request
        {
            get
            {
                return oRequest;
            }
        }
        #endregion
        
        public void Dispose()
        {
            if (WrappedContext != null)
            {
                WrappedContext = null;
            }

            if (MachContext != null)
            {
                MachContext = null;
            }
        }
    }
}
